package common.dal;

import java.sql.*;
import java.util.*;
import java.util.Date;

import msg.*;
import registration.RegistrationManager;
import user.*;

import common.Configuration;
import common.exceptions.*;
import common.logger.*;
import common.logger.Logger.LogLevel;

/**
 * A class that instantiates all the data according to the configuration file, if needed (no drops / deletes will
 * occur).
 * 
 * @author Gal Lalouche
 */
public class Creator {
	
	private static final String	PASSWORD	= "password";
	
	/**
	 * Creates all dbs if needed
	 */
	public static void createAll() {
		// createDB(props);
		Properties props = Configuration.getInstance().getProps();
		try (Transaction t = new Transaction()) {
			LoginManager.getNewInstance(t).getAll();
			MessageManager.getNewInstance(t).getAll();
			User user = LoginManager.getNewInstance(t)
					.registerUser("a" + new Date().getTime(), "tester", PASSWORD);
			EventMessage event = MessageManager.getNewInstance(t)
					.createNewEventMessage(new Location(0, 0), "test event", user, Calendar.getInstance(), 1);
			RegistrationManager.getNewInstance(t).isUserRegisteredToEvent(user, event);
			RegistrationManager.getNewInstance(t).removeAllFromUser(user);
			MessageManager.getNewInstance(t).delete(event.getId());
			try {
				LoginManager.getNewInstance(t).deleteUser(user.getLogin(), PASSWORD);
			} catch (WrongPasswordException e) {
				throw new AssertionError(e);
			}
			t.commit();
			CompositeLogger.getInstance().log(LogLevel.INFO, "all DBs in good shape");
		} catch (SQLException | InvalidEventException | InvalidUserException e) {
			CompositeLogger.getInstance().log(LogLevel.INFO, "recreating all DBs");
			try (Transaction t = new Transaction()) {
				RegistrationManager.getNewInstance(t).drop();
				MessageManager.getNewInstance(t).drop();
				LoginManager.getNewInstance(t).setup();
				MessageManager.getNewInstance(t).setup();
				RegistrationManager.getNewInstance(t).setup();
				t.commit();
				CompositeLogger.getInstance().log(LogLevel.INFO, "setup all DBs");
			} catch (SQLException e1) {
				throw new IllegalStateException(e1);
			}
		}
	}
	
	/**
	 * Creates a new database
	 * 
	 * @param props The properties of the database
	 * @throws SQLException
	 */
	public static void createDB(Properties props) throws SQLException {
		String tempName = props.getProperty("dbName");
		// temporary, to allow database creation
		props.setProperty("dbName", "");
		ConnectionPool pool = new ConnectionPool(1, props);
		props.setProperty("dbName", tempName);
		try (Connection connection = pool.getConnection()) {
			connection.createStatement().execute("CREATE DATABASE IF NOT EXISTS " + tempName);
		}
		pool.closePool();
	}
}
